<script>
import 'tabulator-tables/dist/css/tabulator_bootstrap5.min.css';
import {TabulatorFull as Tabulator} from 'tabulator-tables';
import {formatSize, ChartDateFormatter} from "./formatter.js";

const TIME_FORMATTER = ChartDateFormatter.createDefault();
const DURATION_FORMATTER = new Intl.NumberFormat('en-US');

function minMaxFilterEditor(cell, onRendered, success, cancel, editorParams) {
  let end;
  let container = document.createElement("span");

  let start = document.createElement("input");
  start.setAttribute("placeholder", "Min(10/10KB/20MB..)");
  start.style.width = "50%";
  start.style.boxSizing = "border-box";

  start.value = cell.getValue();

  end = start.cloneNode();
  end.setAttribute("placeholder", "Max(10/10KB/20MB..)");

  function buildValues(){
    success({
      start:start.value,
      end:end.value,
    });
  }

  function keypress(e){
    if(e.keyCode === 13){
      buildValues();
    }

    if(e.keyCode === 27){
      cancel();
    }
  }

  start.addEventListener("change", buildValues);
  start.addEventListener("blur", buildValues);
  start.addEventListener("keydown", keypress);

  end.addEventListener("change", buildValues);
  end.addEventListener("blur", buildValues);
  end.addEventListener("keydown", keypress);

  container.appendChild(start);
  container.appendChild(end);

  return container;
}

function toBytes(s) {
  s = s.trim().toUpperCase();
  if (s.length === 0) {
    return undefined;
  }
  let bNum = parseFloat(s);
  if (s.endsWith('GB') || s.endsWith('G')) {
    return bNum * 1024 * 1024 * 1024;
  } else if (s.endsWith('MB') || s.endsWith('M')) {
    return bNum * 1024 * 1024;
  } else if (s.endsWith('KB') || s.endsWith('K')) {
    return bNum * 1024 * 1024;
  } else {
    return bNum;
  }
}

function minMaxFilterFunction(headerValue, rowValue){
  let start = toBytes(headerValue.start) ?? 0;
  let end = toBytes(headerValue.end) ?? Number.MAX_VALUE;
  return rowValue >= start && rowValue <= end;
}


export default {
  name: "BlocksTable",
  data() {
    return {
      tabulator: null,
    }
  },
  props: {
    onRowClick: {
      type: Function,
      required: true
    }
  },
  methods: {
    setLoading(isLoading) {
      if (isLoading) {
        this.tabulator.alert("Loading...");
      } else {
        this.tabulator.clearAlert();
      }
    },
    updateByPd(pd) {
      this.tabulator.replaceData(pd.blockIdsToBlock);
    }
  },
  mounted() {
    this.tabulator = new Tabulator(this.$refs.table, {
      layout:"fitColumns",
      resizableColumnFit:true,
      pagination:"local",
      paginationSize:20,
      paginationSizeSelector:[10, 20, 50, 100, 200, 500],
      movableColumns:true,
      paginationCounter:"rows",
      rowHeight:38,
      columns: [
        {title:"Id", field:"blockId", sorter: "number"},
        {title:"NodeName", field:"computeNodeName", headerFilter:"input"},
        {title:"Address", field:"address", headerFilter:"input"},
        {title:"Size", field:"size", sorter:"number", formatter: (cell) => formatSize(cell.getValue()),
          headerFilter:minMaxFilterEditor, headerFilterFunc:minMaxFilterFunction, headerFilterLiveFilter:false},
        {title:"StartTime", field:"birthTime", sorter:"number", formatter: (cell) => TIME_FORMATTER.format(cell.getValue())},
        {title:"Duration(us)", field:"duration", sorter: "number", formatter: (cell) => DURATION_FORMATTER.format(cell.getValue())},
        {title:"BirthStream", field:"birthStream"},
      ],
    });
    let onRowClickCallback = this.onRowClick;
    this.tabulator.on("rowClick", function(e, row) {
      onRowClickCallback(row.getData());
    });
  }
}
</script>

<template>
  <div ref="table"></div>
</template>
